HAL FMAC initialization and configuration functions migration

The goal of this page is to show how to migrate the initialization sequence using STM32CubeMX2:

  • Open STM32CubeMX2 FMAC configuration panel.

  • Configure the SW layer HAL.

  • Configure the FMAC main features.

  • Configure the FMAC advanced features.

  • Configure the FMAC DMA(s) if the application requires to use the FMAC in DMA mode.

  • Configure the NVIC if the application requires the FMAC to be used in IT mode.

  • Generate the code.

HAL FMAC configuration panel

Create a new project with the STM32CubeMX2, then start the initialization and the main configuration.

Project configuration panel

HAL FMAC main features configuration

Configure the FMAC main features.

FMAC main feature configuration

HAL FMAC advanced features configuration

Configure the advanced FMAC features.

FMAC advanced feature configuration

DMA configuration

Configure the DMA for data reception as needed.

FMAC DMA configuration

NVIC configuration

Configure the NVIC in case of an interrupt.

FMAC NVIC configuration

Generated FMAC initialization and de-initialization sequences

The FMAC initialization sequence is generated in the mx_fmac_init function in mx_fmac.c file under $YOUR_PROJECT_NAME$/$YOUR_PROJECT_NAME$_SW/generated/STM32Cube_CodeGen.

Related concepts:

Note

In HAL1, the FMAC driver configuration is not generated automatically by STM32CubeMX. It must be added manually to the application code before any process can start. In HAL2, STM32CubeMX2 automatically generates the configuration.

STM32CubeMX2 Generated : FMAC initialization and De-initialization sequence

Topic

HAL1

HAL2

Handle declaration

FMAC_HandleTypeDef hfmac;
static hal_fmac_handle_t hFMAC;

Initialization and configuration sequence

static void MX_FMAC_Init(void)
{
  hfmac.Instance = FMAC;

  if (HAL_FMAC_Init(&hfmac) != HAL_OK)
  {
    Error_Handler();
  }
}

void HAL_FMAC_MspInit(FMAC_HandleTypeDef* hfmac)
{
  if(hfmac->Instance==FMAC)
  {
    /* Peripheral clock enable */
    __HAL_RCC_FMAC_CLK_ENABLE();

    /* FMAC DMA Init */
    /* GPDMA1_REQUEST_FMAC_READ Init */
    handle_GPDMA1_Channel1.Instance = GPDMA1_Channel1;
    handle_GPDMA1_Channel1.Init.Request = GPDMA1_REQUEST_FMAC_READ;
    handle_GPDMA1_Channel1.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
    handle_GPDMA1_Channel1.Init.Direction = DMA_PERIPH_TO_MEMORY;
    handle_GPDMA1_Channel1.Init.SrcInc = DMA_SINC_FIXED;
    handle_GPDMA1_Channel1.Init.DestInc = DMA_DINC_FIXED;
    handle_GPDMA1_Channel1.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_BYTE;
    handle_GPDMA1_Channel1.Init.DestDataWidth = DMA_DEST_DATAWIDTH_BYTE;
    handle_GPDMA1_Channel1.Init.Priority = DMA_LOW_PRIORITY_LOW_WEIGHT;
    handle_GPDMA1_Channel1.Init.SrcBurstLength = 1;
    handle_GPDMA1_Channel1.Init.DestBurstLength = 1;
    handle_GPDMA1_Channel1.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT0;
    handle_GPDMA1_Channel1.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
    handle_GPDMA1_Channel1.Init.Mode = DMA_NORMAL;
    if (HAL_DMA_Init(&handle_GPDMA1_Channel1) != HAL_OK)
    {
      Error_Handler();
    }

    __HAL_LINKDMA(hfmac, hdmaOut, handle_GPDMA1_Channel1);

    if (HAL_DMA_ConfigChannelAttributes(&handle_GPDMA1_Channel1, DMA_CHANNEL_NPRIV) != HAL_OK)
    {
      Error_Handler();
    }

    /* GPDMA1_REQUEST_FMAC_WRITE Init */
    handle_GPDMA1_Channel0.Instance = GPDMA1_Channel0;
    handle_GPDMA1_Channel0.Init.Request = GPDMA1_REQUEST_FMAC_WRITE;
    handle_GPDMA1_Channel0.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
    handle_GPDMA1_Channel0.Init.Direction = DMA_PERIPH_TO_MEMORY;
    handle_GPDMA1_Channel0.Init.SrcInc = DMA_SINC_FIXED;
    handle_GPDMA1_Channel0.Init.DestInc = DMA_DINC_FIXED;
    handle_GPDMA1_Channel0.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_BYTE;
    handle_GPDMA1_Channel0.Init.DestDataWidth = DMA_DEST_DATAWIDTH_BYTE;
    handle_GPDMA1_Channel0.Init.Priority = DMA_LOW_PRIORITY_LOW_WEIGHT;
    handle_GPDMA1_Channel0.Init.SrcBurstLength = 1;
    handle_GPDMA1_Channel0.Init.DestBurstLength = 1;
    handle_GPDMA1_Channel0.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT0;
    handle_GPDMA1_Channel0.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
    handle_GPDMA1_Channel0.Init.Mode = DMA_NORMAL;
    if (HAL_DMA_Init(&handle_GPDMA1_Channel0) != HAL_OK)
    {
      Error_Handler();
    }

    __HAL_LINKDMA(hfmac, hdmaIn, handle_GPDMA1_Channel0);

    if (HAL_DMA_ConfigChannelAttributes(&handle_GPDMA1_Channel0, DMA_CHANNEL_NPRIV) != HAL_OK)
    {
      Error_Handler();
    }

    /* FMAC interrupt Init */
    HAL_NVIC_SetPriority(FMAC_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(FMAC_IRQn);
  }

}
hal_fmac_handle_t *mx_fmac_init(void)
{
  hal_fmac_config_t fmac_config;

  if (HAL_FMAC_Init(&hFMAC, HAL_FMAC) != HAL_OK)
  {
    return NULL;
  }

  HAL_RCC_FMAC_EnableClock();
  fmac_config.x1_buf.base_half_word = 2;
  fmac_config.x1_buf.size_half_word = 12;
  fmac_config.x2_buf.base_half_word = 15;
  fmac_config.x2_buf.size_half_word = 12;
  fmac_config.y_buf.base_half_word = 27;
  fmac_config.y_buf.size_half_word = 12;

  HAL_FMAC_SetConfig(&hFMAC, &fmac_config);

  /* Configure the DMA Write */
  if (HAL_DMA_Init(&hGPDMA1_CH0, HAL_GPDMA1_CH0) != HAL_OK)
  {
    return NULL;
  }

  HAL_RCC_GPDMA1_EnableClock();

  hal_dma_direct_xfer_config_t xfer_cfg_fmac_wr_dma;
  xfer_cfg_fmac_wr_dma.request         = HAL_GPDMA1_REQUEST_FMAC_WR;
  xfer_cfg_fmac_wr_dma.direction       = HAL_DMA_DIRECTION_MEMORY_TO_PERIPH;
  xfer_cfg_fmac_wr_dma.src_inc         = HAL_DMA_SRC_ADDR_INCREMENTED;
  xfer_cfg_fmac_wr_dma.dest_inc        = HAL_DMA_DEST_ADDR_FIXED;
  xfer_cfg_fmac_wr_dma.src_data_width  = HAL_DMA_SRC_DATA_WIDTH_HALFWORD;
  xfer_cfg_fmac_wr_dma.dest_data_width = HAL_DMA_DEST_DATA_WIDTH_HALFWORD;
  xfer_cfg_fmac_wr_dma.priority        = HAL_DMA_PRIORITY_HIGH;

  if (HAL_DMA_SetConfigPeriphDirectXfer(&hGPDMA1_CH0, &xfer_cfg_fmac_wr_dma) != HAL_OK)
  {
    return NULL;
  }

  /* Enable the interruption for GPDMA1_CH0 */
  HAL_CORTEX_NVIC_SetPriority(GPDMA1_CH0_IRQn, HAL_CORTEX_NVIC_PREEMP_PRIORITY_0, HAL_CORTEX_NVIC_SUB_PRIORITY_0);
  HAL_CORTEX_NVIC_EnableIRQ(GPDMA1_CH0_IRQn);

  /* Link the Write X1 DMA handle to the FMAC handle */
  if (HAL_FMAC_SetWriteX1DMA(&hFMAC, &hGPDMA1_CH0) != HAL_OK)
  {
    return NULL;
  }

  /* Configure the DMA Read */
  if (HAL_DMA_Init(&hGPDMA1_CH1, HAL_GPDMA1_CH1) != HAL_OK)
  {
    return NULL;
  }

  HAL_RCC_GPDMA1_EnableClock();

  hal_dma_direct_xfer_config_t xfer_cfg_fmac_rd_dma;
  xfer_cfg_fmac_rd_dma.request         = HAL_GPDMA1_REQUEST_FMAC_RD;
  xfer_cfg_fmac_rd_dma.direction       = HAL_DMA_DIRECTION_PERIPH_TO_MEMORY;
  xfer_cfg_fmac_rd_dma.src_inc         = HAL_DMA_SRC_ADDR_FIXED;
  xfer_cfg_fmac_rd_dma.dest_inc        = HAL_DMA_DEST_ADDR_INCREMENTED;
  xfer_cfg_fmac_rd_dma.src_data_width  = HAL_DMA_SRC_DATA_WIDTH_HALFWORD;
  xfer_cfg_fmac_rd_dma.dest_data_width = HAL_DMA_DEST_DATA_WIDTH_HALFWORD;
  xfer_cfg_fmac_rd_dma.priority        = HAL_DMA_PRIORITY_HIGH;

  if (HAL_DMA_SetConfigPeriphDirectXfer(&hGPDMA1_CH1, &xfer_cfg_fmac_rd_dma) != HAL_OK)
  {
    return NULL;
  }

  /* Enable the interruption for GPDMA1_CH1 */
  HAL_CORTEX_NVIC_SetPriority(GPDMA1_CH1_IRQn, HAL_CORTEX_NVIC_PREEMP_PRIORITY_0, HAL_CORTEX_NVIC_SUB_PRIORITY_0);
  HAL_CORTEX_NVIC_EnableIRQ(GPDMA1_CH1_IRQn);

  /* Link the Read Y DMA handle to the FMAC handle */
  if (HAL_FMAC_SetReadYDMA(&hFMAC, &hGPDMA1_CH1) != HAL_OK)
  {
    return NULL;
  }

  /* Enable the interruption for FMAC */
  HAL_CORTEX_NVIC_SetPriority(FMAC_IRQn, HAL_CORTEX_NVIC_PREEMP_PRIORITY_0, HAL_CORTEX_NVIC_SUB_PRIORITY_0);
  HAL_CORTEX_NVIC_EnableIRQ(FMAC_IRQn);

  return &hFMAC;
}

Deinitialization sequence

void HAL_FMAC_MspDeInit(FMAC_HandleTypeDef* hfmac)
{
  if(hfmac->Instance==FMAC)
  {
    /* Peripheral clock disable */
    __HAL_RCC_FMAC_CLK_DISABLE();

    /* FMAC DMA DeInit */
    HAL_DMA_DeInit(hfmac->hdmaOut);
    HAL_DMA_DeInit(hfmac->hdmaIn);

    /* FMAC interrupt DeInit */
    HAL_NVIC_DisableIRQ(FMAC_IRQn);
  }
}
void mx_fmac_deinit(void)
{

  /* Disable the interruption for FMAC */
  HAL_CORTEX_NVIC_DisableIRQ(FMAC_IRQn);
  HAL_FMAC_DeInit(&hFMAC);

  HAL_RCC_FMAC_Reset();
  HAL_RCC_FMAC_DisableClock();

  /* De-initialize the DMA channel */
  HAL_DMA_DeInit(&hGPDMA1_CH0);

  /* Disable the interruption for DMA */
  HAL_CORTEX_NVIC_DisableIRQ(GPDMA1_CH0_IRQn);

  /* De-initialize the DMA channel */
  HAL_DMA_DeInit(&hGPDMA1_CH1);

  /* Disable the interruption for DMA */
  HAL_CORTEX_NVIC_DisableIRQ(GPDMA1_CH1_IRQn);
}

IRQ handle function

void FMAC_IRQHandler(void)
{
  HAL_FMAC_IRQHandler(&hfmac);
}
void FMAC_IRQHandler(void)
{
  HAL_FMAC_IRQHandler(&hFMAC);
}